package hd.util;

import android.os.Handler;
import android.os.Message;
import android.view.View;

/**
 * view动画
 * <p/>
 * Created by Haidy on 14-10-9.
 */
public class ViewAnimation {

    private int duration = 250;//动画时间

    private OnAnimationListener onAnimationListener;
    private int scrollModel = ACCELERATION;//运动模式，默认为加速

    public static final int ACCELERATION = 0; //加速
    public static final int DECELERATION = 1; //减速
    private boolean isScrolling = false;

    private boolean stopScrolling = false;

    /**
     * 设置动画时间
     *
     * @param duration 时间
     */
    public void setDuration(int duration) {
        this.duration = duration;
    }

    /**
     * 获取动画时间
     *
     * @return 时间
     */
    public int getDuration() {
        return duration;
    }

    /**
     * 开始动画
     *
     * @param view   要移动的视图
     * @param startX startX
     * @param startY startY
     * @param moveX  moveX
     * @param moveY  moveY
     */
    public void startAnimation(final View view, final int startX, final int startY, final int moveX, final int moveY) {
        if (onAnimationListener != null) {
            onAnimationListener.onAnimationStart();
        }
        isScrolling = true;
        new Thread() {
            @Override
            public void run() {
                switch (scrollModel) {
                    case ACCELERATION: // 加速
                        acceleration(view, startX, startY, moveX, moveY);
                        break;
                    case DECELERATION: // 减速
                        decelerate(view, startX, startY, moveX, moveY);
                        break;
                }
            }
        }.start();
    }


    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            ((View) msg.obj).scrollTo(msg.arg1, msg.arg2);
            isScrolling = msg.what == 0;
            if (onAnimationListener != null) {
                onAnimationListener.onScrollTo(msg.arg1, msg.arg2);
                if (msg.what == 1) {
                    onAnimationListener.onAnimationStop();
                }
            }
        }
    };

    /**
     * 设置滑动的模式
     *
     * @param scrollModel 滑动模式（加速，减速）
     */
    public void setScrollModel(int scrollModel) {
        this.scrollModel = scrollModel;
    }

    /**
     * 减速运动
     *
     * @param view   view
     * @param startX startX
     * @param startY startY
     * @param moveX  moveX
     * @param moveY  moveY
     */
    private void decelerate(View view, int startX, int startY, int moveX, int moveY) {
        int time = duration;
        float aX = 2.0f * moveX / (duration * duration);
        float aY = 2.0f * moveY / (duration * duration);
        while (time > 0 && !stopScrolling) {
            int moveToX = (int) (aX * time * time / 2.0f), moveToY = (int) (aY * time * time / 2.0f);
            Message msg = new Message();
            msg.obj = view;
            msg.arg1 = startX + (moveX - moveToX);
            msg.arg2 = startY + (moveY - moveToY);
            msg.what = 0;
            handler.sendMessage(msg);
            try {
                Thread.sleep(16);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            time -= 16;
        }
        if (!stopScrolling) {
            Message msg = new Message();
            msg.obj = view;
            msg.arg1 = startX + moveX;
            msg.arg2 = startY + moveY;
            msg.what = 1;
            handler.sendMessage(msg);
        } else {
            isScrolling = stopScrolling = false;
        }
    }

    /**
     * 加速运动
     *
     * @param view   view
     * @param startX startX
     * @param startY startY
     * @param moveX  moveX
     * @param moveY  moveY
     */
    private void acceleration(View view, int startX, int startY, int moveX, int moveY) {
        int time = 16;
        float aX = 2.0f * moveX / (duration * duration);
        float aY = 2.0f * moveY / (duration * duration);
        while (time < duration && !stopScrolling) {
            int moveToX = (int) (aX * time * time / 2.0f), moveToY = (int) (aY * time * time / 2.0f);
            Message msg = new Message();
            msg.obj = view;
            msg.arg1 = startX + moveToX;
            msg.arg2 = startY + moveToY;
            msg.what = 0;
            handler.sendMessage(msg);
            try {
                Thread.sleep(16);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            time += 16;
        }
        if (!stopScrolling) {
            Message msg = new Message();
            msg.obj = view;
            msg.arg1 = startX + moveX;
            msg.arg2 = startY + moveY;
            msg.what = 1;
            handler.sendMessage(msg);
        } else {
            isScrolling = stopScrolling = false;
        }
    }

    /**
     * 设置动画监听
     *
     * @param onAnimationListener 监听器
     */
    public void setOnAnimationListener(OnAnimationListener onAnimationListener) {
        this.onAnimationListener = onAnimationListener;
    }

    /**
     * 停止滑动
     */
    public void stopScrolling() {
        stopScrolling = true;
    }

    /**
     * 是否在滑动
     *
     * @return 是否在滑动
     */
    public boolean isScrolling() {
        return isScrolling;
    }

    /**
     * 动画操作接口
     */
    public interface OnAnimationListener {

        void onAnimationStart();//开始动画

        void onScrollTo(int pixelX, int pixelY);

        void onAnimationStop();//结束动画
    }

}